package br.com.tcc.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.NoResultException;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.apache.log4j.Logger;

import br.com.tcc.model.Anunciante;
import br.com.tcc.model.Categoria;
import br.com.tcc.model.Produto;

public class ProdutoDao {
	private EntityManagerFactory emf;
	Logger logger = Logger.getLogger(ProdutoDao.class);
	
	public ProdutoDao() {
		emf = Persistence.createEntityManagerFactory("persistencia");
	}
	
	public boolean adicionar(Produto produto) {
		EntityManager em = emf.createEntityManager();
		boolean retorno = true;
		try{
			em.getTransaction().begin();
			em.persist(produto);
			em.getTransaction().commit();
		}catch(Exception e){
			em.getTransaction().rollback();
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
			retorno = false;
			em.close();
		}finally{
			em.close();
		}
	   	return retorno;
	}

	public List<Produto> listarProdutos() {
		List<Produto> retorno = null;
		EntityManager em = emf.createEntityManager();
		
		try{
		   	em.getTransaction().begin();
		   	Query q = em.createQuery("select p from Produto p order by p.nome");
		   	q.setMaxResults(100);
		   	retorno = q.getResultList();
		}catch (NoResultException e) {
			logger.info("sem registro");
		}catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		}finally{
			em.close();
		}
		return retorno;
	}
	
	public List<Produto> listarProdutosParaAnunciante(Anunciante anunciante, Categoria categoria) {
		List<Produto> retorno = null;
		EntityManager em = emf.createEntityManager();
		
		try{
		   	em.getTransaction().begin();
		   	String sql = "select p from Produto p, ProdutoAndAnunciante pAnunc where  p.id = pAnunc.produto.id and  pAnunc.anunciante.idAnunciante = :idAnunciante ";
		   
		   	if (categoria != null && categoria.getIdCategoria() != 0) {
				sql = sql + " and ( p.categoriaNivel0 = :idCategoria OR p.categoriaNivel1 =:idCategoria" +
					" OR p.categoriaNivel2 =:idCategoria OR p.categoriaNivel3 =:idCategoria ) order by p.nome";
		   	}else {
				sql = sql + " order by p.nome";
			}
		   	
		   	 logger.info("listarProdutosParaAnunciante(Anunciante anunciante, Categoria categoria)");
		   	 logger.info("SQL = " +sql);
		   	 
			Query q = em.createQuery(sql);
		   	
		   	q.setParameter("idAnunciante", anunciante.getIdAnunciante());
		   	
		   	if (categoria != null && categoria.getIdCategoria() != 0) 
		   		q.setParameter("idCategoria", categoria.getIdCategoria());
			
		   	retorno = q.getResultList();
		}catch (NoResultException e) {
			logger.info("sem registro");
		}catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		}finally{
			em.close();
		}
		return retorno;
	}
	
	
	public Produto buscarCodigoBarra(String codigoBarra) {
		Produto retorno = null;
		EntityManager em = emf.createEntityManager();
		try{
		   	em.getTransaction().begin();
		   	Query q = em.createQuery("select p from Produto p where p.codigoBarra=:codigoBarra");
		   	q.setParameter("codigoBarra", codigoBarra);
		   	retorno = (Produto) q.getSingleResult();
	   	
		}catch (NoResultException e) {
			logger.info("sem registro");
		}catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		}finally{
			em.close();
		}
		
		return retorno;
	}

	public List<Produto> pesquisar(String texto) {
		List<Produto> retorno = null;
		EntityManager em = emf.createEntityManager();
		try{
		   	em.getTransaction().begin();
		   	
		   	Query q = em.createQuery("select p from Produto p " +
		   							 "where p.nome like '%"+texto.trim()+"%' ");
		   	
		   	logger.info("procurando por: " +texto.trim());
		   	
		   	retorno = q.getResultList();
		}catch (NoResultException e) {
			logger.info("sem registro");
		}catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		}finally{
			em.close();
		}
		return retorno;
	}
	
	public Produto buscarId(int id){
		Produto retorno = null;
		EntityManager em = emf.createEntityManager();
		try{
		   	em.getTransaction().begin();
		   	retorno = em.find(Produto.class, id);
		}catch (NoResultException e) {
			logger.info("sem registro");
		}catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		}finally{
			em.close();
		}
		return retorno;
	}
	
	/**
	 * Buscar os produtos por categoria e anunciante
	 * @param categoria
	 * @return
	 */
	public List<Produto> buscarProdutosCategoria(Categoria categoria, Anunciante anunciante) {
		List<Produto> listProdutos = null;
		EntityManager em = emf.createEntityManager();
		
		try {
			em.getTransaction().begin();
			String sql = ("select p from Produto p, ProdutoAndAnunciante pAnunc where ( p.categoriaNivel0 = :idCategoria OR p.categoriaNivel1 =:idCategoria" +
					" OR p.categoriaNivel2 =:idCategoria OR p.categoriaNivel3 =:idCategoria ) ");
			
			//Se o filtro para anunciante estiver selecionado
			if (anunciante != null && anunciante.getIdAnunciante() != 0) 
				sql = sql + " and ( p.id = pAnunc.produto.id and pAnunc.anunciante.idAnunciante = :idAnunciante ) order by p.nome";
			else 
				sql = sql + " GROUP BY p.nome order by p.nome"; 
			
				
			logger.info("SQL = " +sql);
			
			Query q = em.createQuery(sql);

			q.setParameter("idCategoria", categoria.getIdCategoria());
			if (anunciante != null && anunciante.getIdAnunciante() != 0) 
				q.setParameter("idAnunciante", anunciante.getIdAnunciante());
			
			listProdutos = q.getResultList();
		} catch (Exception e) {
			logger.warn("Erro no metodo  [ " + e.getMessage() + " ]");
		}
		return listProdutos;
	}
}